package com.neurosky.demo;


import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;

import com.neurosky.connection.ConnectionStates;
import com.neurosky.connection.TgStreamHandler;
import com.neurosky.connection.TgStreamReader;
import com.neurosky.connection.DataType.BodyDataType;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.LayoutInflater;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.neurosky.ecg.TGLibECG;
import com.neurosky.ecg.TGLibECGCallback;


public class DemoActivity extends Activity {
	private static final String TAG = DemoActivity.class.getSimpleName();
	private static final String SHAREFILENAME = "Neurosky";
	
	private static final String ZOOM_MODE = "zoom_mode";
	private static final String GRID_MODE = "grid_mode";
	
	private static final String USER_NAME = "user_name";
	private static final String USER_GENDER = "user_gender";
	private static final String USER_AGE = "user_age";
	private static final String USER_HEIGHT = "user_height";
	private static final String USER_WEIGHT = "user_weight";
	private static final String DISPLAY_MODE="display_mode";
	
	
	

	private TgStreamReader tgStreamReader;

	// TODO connection sdk
	private BluetoothAdapter mBluetoothAdapter;
	
	private SharedPreferences sharePreferences;
	private SharedPreferences.Editor shareEditor;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		TgStreamReader.redirectConsoleLogToDocumentFolder();
		sharePreferences = getSharedPreferences(SHAREFILENAME, Activity.MODE_PRIVATE);
        shareEditor = sharePreferences.edit();
        initUserProfile();
		setContentView(R.layout.main_view);

		initView();
		setUpDrawWaveView();

		try {
			// TODO	
			mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
				Toast.makeText(
						this,
						"Please enable your Bluetooth and re-run this program !",
						Toast.LENGTH_LONG).show();
				finish();
//				return;
			}  
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			Log.i(TAG, "error:" + e.getMessage());
			return;
		}
		libECG = new TGLibECG(ecgCallback);
		libECG.enableLogCatMessages(true);
		
		tv_appversion.setText(getVersionString());
	}

	private LinearLayout wave_layout;
	
	private int badPacketCount = 0;
	
	private Button btn_zoom = null;
	private Button btn_grid = null;
	
	private TextView  tv_stress_lable = null;
	private TextView  tv_stress = null;
	private TextView  tv_signalquality_label = null;
	private TextView  tv_signalquality = null;
	private TextView  tv_rrinterval_label = null;
	private TextView  tv_rrinterval = null;
	
	private TextView  tv_heartrate_label = null;
	private TextView  tv_heartrate = null;
	private TextView  tv_robusthr_label = null;
	private TextView  tv_robusthr = null;
	
	private TextView  tv_hrv_label = null;
	private TextView  tv_hrv = null;
	private TextView  tv_mood_label = null;
	private TextView  tv_mood = null;
	private TextView  tv_heartage_label = null;
	private TextView  tv_heartage = null;
	
	private TextView  tv_rpeak = null;
	private TextView  tv_rpeak_label = null;
	private TextView  tv_heartbeat = null;
	private TextView  tv_heartbeat_label = null;
	private TextView  tv_osq = null;
	private TextView  tv_osq_label = null;
    
	private Button btn_setprofile = null;
	private Button btn_start = null;
	private Button btn_stop = null;
	private Button btn_mode = null;
	
	private TextView tv_appversion = null;

	private void initView() {
		boolean zoom_flag;
		boolean grid_flag;
		
		btn_zoom = (Button) findViewById(R.id.btn_zoom);
		zoom_flag = sharePreferences.getBoolean(ZOOM_MODE, false);
		updateZoomText(zoom_flag);
		
		btn_grid = (Button) findViewById(R.id.btn_grid);
		grid_flag = sharePreferences.getBoolean(GRID_MODE, true);
		updateGridText(grid_flag);

		wave_layout = (LinearLayout) findViewById(R.id.wave_layout);

		updateWaveBackground(grid_flag, zoom_flag);
		
		boolean display_flag = sharePreferences.getBoolean(DISPLAY_MODE, true);
		btn_mode = (Button) findViewById(R.id.btn_mode);
		if(display_flag){
			btn_mode.setText("Simple Mode");
		}else{
			btn_mode.setText("Full Mode");
		}
		
		tv_stress_lable = (TextView) findViewById(R.id.tv_stress_lable);
		tv_stress = (TextView) findViewById(R.id.tv_stress);
		tv_signalquality_label = (TextView) findViewById(R.id.tv_signalquality_label);
		tv_signalquality = (TextView) findViewById(R.id.tv_signalquality);
		tv_rrinterval_label = (TextView) findViewById(R.id.tv_rrinterval_label);
		tv_rrinterval = (TextView) findViewById(R.id.tv_rrinterval);
		
		tv_heartrate_label = (TextView) findViewById(R.id.tv_heartrate_label);
		tv_heartrate = (TextView) findViewById(R.id.tv_heartrate);
		tv_robusthr_label = (TextView) findViewById(R.id.tv_robusthr_label);
		tv_robusthr = (TextView) findViewById(R.id.tv_robusthr);
		
		tv_hrv_label = (TextView) findViewById(R.id.tv_hrv_label);
		tv_hrv = (TextView) findViewById(R.id.tv_hrv);
		tv_mood_label = (TextView) findViewById(R.id.tv_mood_label);
		tv_mood = (TextView) findViewById(R.id.tv_mood);
		tv_heartage_label = (TextView) findViewById(R.id.tv_heartage_label);
		tv_heartage = (TextView) findViewById(R.id.tv_heartage);
		
		tv_rpeak = (TextView) findViewById(R.id.tv_rpeak);
		tv_rpeak_label = (TextView) findViewById(R.id.tv_rpeak_label);
		tv_heartbeat = (TextView) findViewById(R.id.tv_heartbeat);
		tv_heartbeat_label = (TextView) findViewById(R.id.tv_heartbeat_label);
		tv_osq = (TextView) findViewById(R.id.tv_osq);
		tv_osq_label = (TextView) findViewById(R.id.tv_osq_label);
		if(display_flag){
			tv_rpeak.setVisibility(View.VISIBLE);
			tv_heartbeat.setVisibility(View.VISIBLE);
			tv_osq.setVisibility(View.VISIBLE);
			tv_rpeak_label.setVisibility(View.VISIBLE);
			tv_heartbeat_label.setVisibility(View.VISIBLE);
			tv_osq_label.setVisibility(View.VISIBLE);
			
		}else{
			tv_heartbeat.setVisibility(View.INVISIBLE);
			tv_rpeak.setVisibility(View.INVISIBLE);
			tv_osq.setVisibility(View.INVISIBLE);
			tv_rpeak_label.setVisibility(View.VISIBLE);
			tv_heartbeat_label.setVisibility(View.VISIBLE);
			tv_osq_label.setVisibility(View.VISIBLE);
		}
		
		btn_setprofile = (Button) findViewById(R.id.btn_setprofile);
		btn_start = (Button) findViewById(R.id.btn_start);
		btn_stop = (Button) findViewById(R.id.btn_stop);
		

		
		tv_appversion = (TextView) findViewById(R.id.tv_appversion);
		
		setClickListener();
		

	}
	private void setClickListener(){
		btn_zoom.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// 1. update share preference
				boolean zoom_flag = sharePreferences.getBoolean(ZOOM_MODE, false);
				shareEditor.putBoolean(ZOOM_MODE, !zoom_flag);
				shareEditor.commit();
				
				// 2. update zoom button text
				updateZoomText(!zoom_flag);
				
				// 3. update background
				boolean grid_flag = sharePreferences.getBoolean(GRID_MODE, true);
				updateWaveBackground(grid_flag, !zoom_flag);
				
				// 4. update drawing style
				updateWaveViewPara(!zoom_flag);
			}

		});
		btn_grid.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				boolean grid_flag = sharePreferences.getBoolean(GRID_MODE, true);
				boolean zoom_flag = sharePreferences.getBoolean(ZOOM_MODE, false);
				shareEditor.putBoolean(GRID_MODE, !grid_flag);
				shareEditor.commit();
				
				updateGridText(!grid_flag);
				updateWaveBackground(!grid_flag, zoom_flag);
			}

		});
		btn_setprofile.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				showProfileDialog();
			}

		});
		
		btn_start.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				badPacketCount = 0;
				if(tgStreamReader != null){
					tgStreamReader.stop();
					tgStreamReader.close();
					tgStreamReader = null;
				}
				
				//reset views
				tv_stress.setText("");
				tv_heartage.setText("");
				tv_heartbeat.setText("");
				tv_heartrate.setText("");
				tv_hrv.setText("");
				tv_mood.setText("");
				tv_osq.setText("");
				tv_robusthr.setText("");
				tv_rpeak.setText("");
				tv_rrinterval.setText("");
				tv_signalquality.setText("");
				tv_stress.setText("");
				
				tgStreamReader = new TgStreamReader(mBluetoothAdapter,callback);
				resetECG();
				tgStreamReader.connectAndStart();
				tgStreamReader.setGetDataTimeOutTime(6);//5s for default
				tgStreamReader.startLog();
				
				
			}
		});

		btn_stop.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				LinkDetectedHandler.sendEmptyMessage(MSG_UPDATE_OVERALL_SINGNAL_QUALITY);
				stop();
			}

		});
		btn_mode.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				boolean display_flag = sharePreferences.getBoolean(DISPLAY_MODE, true);
				shareEditor.putBoolean(DISPLAY_MODE, !display_flag);
				shareEditor.commit();
				if(!display_flag){
					btn_mode.setText("Simple Mode");
					tv_rpeak.setVisibility(View.VISIBLE);
					tv_heartbeat.setVisibility(View.VISIBLE);
					tv_osq.setVisibility(View.VISIBLE);
					tv_rpeak_label.setVisibility(View.VISIBLE);
					tv_heartbeat_label.setVisibility(View.VISIBLE);
					tv_osq_label.setVisibility(View.VISIBLE);
					
				}else{
					btn_mode.setText("Full Mode");
					tv_rpeak.setVisibility(View.INVISIBLE);
					tv_heartbeat.setVisibility(View.INVISIBLE);
					tv_osq.setVisibility(View.INVISIBLE);
					tv_rpeak_label.setVisibility(View.INVISIBLE);
					tv_heartbeat_label.setVisibility(View.INVISIBLE);
					tv_osq_label.setVisibility(View.INVISIBLE);
				}
			}

		});	
	}
	
	public  String getVersionString(){
		PackageManager pm = this.getPackageManager();
		String packageVersion = null;
		try {
			PackageInfo info = pm.getPackageInfo(this.getPackageName(), 0);
			packageVersion = info.versionName;
		} catch (NameNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			packageVersion = "unknow version";
		}
		Log.d(TAG,"Algo SDK Version:   " + libECG.getVersion());
	
		return "App Version: " + packageVersion + "     SDK Version: " + libECG.getVersion()+" / " + TgStreamReader.getVersion();
	}
	
	private void updateZoomText(boolean flag){
		if(btn_zoom == null){
			return;
		}
		if(flag){
			btn_zoom.setText("1X");
		}else{
			btn_zoom.setText("2X");
		}
	}
	private void updateGridText(boolean grid_flag){
		if(btn_grid == null){
			return;
		}
		if(grid_flag){
			btn_grid.setText("Grid off");
		}else{
			btn_grid.setText("Grid on");
		}
	}
	
	private void updateWaveBackground(boolean grid_flag, boolean zoom_flag){
		if(wave_layout == null){
			return;
		}
		if(grid_flag){
			if(zoom_flag){
				wave_layout.setBackgroundResource(R.drawable.x2);
			}else{
				wave_layout.setBackgroundResource(R.drawable.x1);
			}
		}else{
			wave_layout.setBackgroundResource(R.drawable.x3);
		}
	}
	
	private void updateWaveViewPara(boolean zoom_flag){
		if(waveView == null){
			return;
		}
		
		if(zoom_flag){
			waveView.setValue(1024, 4000, -4000);
		}else{
			waveView.setValue(2048, 8000, -8000);
		}
		waveView.updateDensity();
	}

	public void stop() {
		if(tgStreamReader != null){
			tgStreamReader.stop();
			tgStreamReader.close();
			tgStreamReader = null;
		}
	}

	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		if(tgStreamReader != null){
			tgStreamReader.close();
		}
		TgStreamReader.stopConsoleLog();
		super.onDestroy();
	}

	@Override
	protected void onStart() {
		super.onStart();
	}

	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		stopRecordRawData();
		super.onStop();
	}
	
	private BufferedOutputStream outputStreamRawData = null;
	public void startRecordRawData(){
		if(!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())){
			Log.e(TAG,"SD do not mounted:" + Environment.getExternalStorageState() );
			return ;
		}
		String path = Environment.getExternalStorageDirectory() +"/neurosky/NSDemoApp/RawData/";
		File dir = new File(path);
		if(!dir.exists()) dir.mkdirs();
		SimpleDateFormat dateFormatGmt = new SimpleDateFormat("yyyyMMdd_HH_mm_ss");
		String fileName = sharePreferences.getString(USER_NAME, "User") + "_" + dateFormatGmt.format(new Date())+".txt";

		File outputFile = new File(dir, fileName);
		outputStreamRawData = null;
		try {
			outputStreamRawData =  new BufferedOutputStream(new FileOutputStream(outputFile),100*1024);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void stopRecordRawData(){
		if(outputStreamRawData == null){
			return;
		}
		try {
			outputStreamRawData.flush();
			outputStreamRawData.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			outputStreamRawData = null;
		}
	}

	// TODO view
	DrawWaveView waveView = null;
	

	public void setUpDrawWaveView() {
		// TODO use self view to drawing ECG
		waveView = new DrawWaveView(getApplicationContext());
		wave_layout.addView(waveView, new LayoutParams(
				LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
		if(sharePreferences.getBoolean(ZOOM_MODE, false)){
			waveView.setValue(1024, 4000, -4000);
		}else{
			waveView.setValue(2048, 8000, -8000);
		}
		
	}

	public void updateWaveView(int data) {
		if (waveView != null) {
			waveView.updateData(data);
		}
	}
   private boolean isWorking = false;
	private TgStreamHandler callback = new TgStreamHandler() {

		@Override
		public void onStatesChanged(int connectionStates) {
			// TODO Auto-generated method stub
			Log.d(TAG, "connectionStates change to: " + connectionStates);
			switch (connectionStates) {
			case ConnectionStates.STATE_CONNECTED:
				//sensor.start();
				showToast("Connected", Toast.LENGTH_SHORT);
				poorSignal = 0;
				break;
			case ConnectionStates.STATE_WORKING:

				isFirstRaw = true;
				isWorking = true;
				startRecordRawData();
				break;
			case ConnectionStates.STATE_GET_DATA_TIME_OUT:
				// can't get data
				if(isWorking){
					isStopped = true;
					LinkDetectedHandler.sendEmptyMessage(MSG_UPDATE_OVERALL_SINGNAL_QUALITY);
					isWorking =  false;
					stopRecordRawData();
				}
				showToast("Get data timeout", Toast.LENGTH_SHORT);
				break;
			case ConnectionStates.STATE_STOPPED:
				if(isWorking){
					//LinkDetectedHandler.sendEmptyMessage(MSG_UPDATE_OVERALL_SINGNAL_QUALITY);
					isStopped = true;
					isWorking =  false;
					stopRecordRawData();
					showToast("Stopped", Toast.LENGTH_SHORT);
				}
				break;
			case ConnectionStates.STATE_DISCONNECTED:
				
				break;
			case ConnectionStates.STATE_ERROR:
				break;
			case ConnectionStates.STATE_FAILED:
				showToast("Connect failed!", Toast.LENGTH_SHORT);
				break;
			}
			Message msg = LinkDetectedHandler.obtainMessage();
			msg.what = MSG_UPDATE_STATE;
			msg.arg1 = connectionStates;
			LinkDetectedHandler.sendMessage(msg);
			

		}

		@Override
		public void onRecordFail(int a) {
			// TODO Auto-generated method stub
			Log.e(TAG,"onRecordFail: " +a);

		}

		@Override
		public void onChecksumFail(byte[] payload, int length, int checksum) {
			// TODO Auto-generated method stub
			
			badPacketCount ++;
			Message msg = LinkDetectedHandler.obtainMessage();
			msg.what = MSG_UPDATE_BAD_PACKET;
			msg.arg1 = badPacketCount;
			LinkDetectedHandler.sendMessage(msg);

		}

		@Override
		public void onDataReceived(int datatype, int data, Object obj) {
			// TODO Auto-generated method stub
			Message msg = LinkDetectedHandler.obtainMessage();
			msg.what = datatype;
			msg.arg1 = data;
			msg.obj = obj;
			LinkDetectedHandler.sendMessage(msg);
			//Log.i(TAG,"onDataReceived");
		}

	};

	private static final int MSG_UPDATE_PRESSING_STATE = 1000;
	private static final int MSG_UPDATE_BAD_PACKET = 1001;
	private static final int MSG_UPDATE_STATE = 1002;
	private static final int MSG_UPDATE_SINGNAL_QUALITY = 1003;
	private static final int MSG_UPDATE_OVERALL_SINGNAL_QUALITY = 1004;
	
	private volatile int poorSignal = 0;  //reset it when connected
	private boolean isPress = false;
	private boolean isFirstRaw = false;
	private boolean isStopped = false;

	int raw;
	private Handler LinkDetectedHandler = new Handler() {

		@Override
		public void handleMessage(Message msg) {

			switch (msg.what) {
			
			
			case BodyDataType.CODE_RAW:// 
				if(poorSignal == 0){
					return;
				}
				libECG.requestECGAnalysis(msg.arg1, poorSignal);
				if(outputStreamRawData != null){
					String buf = msg.arg1 + "\n";
					try {
						outputStreamRawData.write(buf.getBytes());
					} catch (IOException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				break;			
			
			case BodyDataType.CODE_POOR_SIGNAL:
				poorSignal = msg.arg1;
				if(poorSignal != 0 && poorSignal != 200){
					Log.d(TAG, "poorSignal:" + poorSignal);
				}
				if(isFirstRaw){
					isFirstRaw = false;
					isStopped = false;
					LinkDetectedHandler.sendEmptyMessageDelayed(MSG_UPDATE_SINGNAL_QUALITY,4000);
				}
				
				if(isPress){
					if(poorSignal == 0){ // stop when release fingers
						isPress = false;
						LinkDetectedHandler.sendEmptyMessage(MSG_UPDATE_OVERALL_SINGNAL_QUALITY);
						stop();
					}
				}else{
					if(poorSignal > 0){
						isPress = true;
					}
				}

				break;
			case MSG_UPDATE_BAD_PACKET:
				//tv_badpacket.setText("" + msg.arg1);
				Log.d(TAG, "Bad packet: " + msg.arg1);
				
				break;
			case MSG_UPDATE_STATE:
				//tv_connection.setText(""+msg.arg1);
				break;
			case MSG_UPDATE_OVERALL_SINGNAL_QUALITY:
				tv_osq.setText("" + libECG.getOverallSignalQuality() );
				break;
				
			case MSG_UPDATE_SINGNAL_QUALITY:
				if(!isStopped){
					tv_signalquality.setText("" + libECG.getSignalQuality());
					LinkDetectedHandler.sendEmptyMessageDelayed(MSG_UPDATE_SINGNAL_QUALITY,4000);
				}
				break;
				
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};
	
	
	public void showToast(final String msg,final int timeStyle){
		DemoActivity.this.runOnUiThread(new Runnable()    
        {    
            public void run()    
            {    
            	Toast.makeText(getApplicationContext(), msg, timeStyle).show();
            }    
    
        });  
	}
	
	private EditText et_username = null;
	private RadioGroup rg_gender = null;
	private RadioButton rb_female = null;
	private RadioButton rb_male = null;
	private EditText et_age = null;
	private EditText et_height = null;
	private EditText et_weight = null;
	private void initProfileDialog(View view){
		et_username = (EditText)view.findViewById(R.id.et_username);
		et_username.setText(user_name);
		rg_gender = (RadioGroup)view.findViewById(R.id.rg_gender);
		rb_female = (RadioButton)view.findViewById(R.id.rb_female);
		rb_male = (RadioButton)view.findViewById(R.id.rb_male);
		if(female){
			rb_female.setChecked(true);
		}else{
			rb_male.setChecked(true);
		}
		et_age = (EditText)view.findViewById(R.id.et_age);
		et_age.setText("" + age);
		et_height = (EditText)view.findViewById(R.id.et_height);
		et_height.setText("" + height);
		et_weight = (EditText)view.findViewById(R.id.et_weight);
		et_weight.setText("" + weight);
	}
	private void showProfileDialog(){
		LayoutInflater inflater = LayoutInflater.from(DemoActivity.this);
		final View popView = inflater.inflate(R.layout.pop_view, null);
		initProfileDialog(popView);
		final AlertDialog.Builder builder =new AlertDialog.Builder(DemoActivity.this);
		builder.setCancelable(false);
		builder.setTitle("Set Profile");
		builder.setView(popView);
		builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){

			@Override
			public void onClick(DialogInterface arg0, int arg1) {
				// TODO Auto-generated method stub
				
			}

		});
		builder.setPositiveButton("Save", new DialogInterface.OnClickListener(){

			@Override
			public void onClick(DialogInterface arg0, int arg1) {
				// TODO Auto-generated method stub
				String errorInfo = "";
				String name = et_username.getText().toString();
				if(name != null &&  !"".equals(name)){
					user_name = name;
				}else{
					errorInfo += "Name is invalid;";
				}
				
				if(rb_female.isChecked()){
					female = true;
				}else{
					female = false;
				}
				
				String ageText = et_age.getText().toString();
				try{
				    int age1 =Integer.parseInt(ageText);
				    if(age1 >90 || age1 < 16){
				    	errorInfo += "Age is invalid;";
				    }else{
				    	age = age1;
				    }
				}catch(NumberFormatException e){
					errorInfo += "Age is invalid;";
				}
				
				String heightText = et_height.getText().toString();
				try{
				    int height1 =Integer.parseInt(heightText);
				    if(height1 >300 || height1 < 1){
				    	errorInfo += "height is invalid;";
				    }else{
				    	height = height1;
				    }
				}catch(NumberFormatException e){
					errorInfo += "height is invalidate;";
				}
				
				String weightText = et_weight.getText().toString();
				try{
				    int weight1 =Integer.parseInt(weightText);
				    if(weight1 >300 || weight1 < 1){
				    	errorInfo += "weight is invalid;";
				    }else{
				    	weight = weight1;
				    }
				}catch(NumberFormatException e){
					errorInfo += "weight is invalidate;";
				}
				
				saveUserProfile();
				if(!"".equals(errorInfo)){
					showToast(errorInfo,Toast.LENGTH_SHORT);
				}
			}

		});
		builder.show();
		
	}
	
	//*************************  Algo section  ********************/
	
	private TGLibECG libECG;
	private int outputInterval = 30;
	private int heartAgeRecordNumber = 1;
	private int threshold = 3;
	private String user_name = "User";
	private int weight = 65;
	private int height = 170;
	private int age = 30;
	private boolean female = true;
	private String path = "";
	
	private void initUserProfile(){
		user_name = sharePreferences.getString(USER_NAME, "User");
		female = sharePreferences.getBoolean(USER_GENDER, true);
		age = sharePreferences.getInt(USER_AGE, 30);
		weight = sharePreferences.getInt(USER_WEIGHT, 65);
		height = sharePreferences.getInt(USER_HEIGHT, 170);
	}
	
	private void saveUserProfile(){
		shareEditor.putString(USER_NAME,user_name);
		shareEditor.putBoolean(USER_GENDER, female);
		shareEditor.putInt(USER_AGE, age);
		shareEditor.putInt(USER_WEIGHT, weight);
		shareEditor.putInt(USER_HEIGHT, height);
		shareEditor.commit();
	}
	
	private void resetECG() {		
		libECG.resetECGAnalysis();
		libECG.setSignalQualityThreshold(threshold);
		libECG.setHRVOutputInterval(outputInterval);
		libECG.setMoodOutputPoint(outputInterval);
		libECG.setHeartAgeOutputPoint(outputInterval);
		libECG.setHeartAgeParameters(user_name, age, path);
		libECG.setHeartAgeRecordNumber(heartAgeRecordNumber);
		libECG.setStressOutputInterval(outputInterval);
		libECG.setStressParameters(user_name, female, age, height, weight, path);
		
		//libECG.getVersion();

	}
	
	public TGLibECGCallback ecgCallback = new TGLibECGCallback() {
		@Override
		public void dataReceived(int key, Object data) {
			runOnUiThread(new ecgData(key, data));
		}
	};

	public class ecgData implements Runnable {
		int key;
		Object data;

		public ecgData(int k, Object d) {
			key = k;
			data = d;
		}

		@Override
		public void run() {
			switch (key) {
			case TGLibECG.MSG_ECG_SMOOTHED_WAVE:
				updateWaveView((Integer) data);
				break;
			case TGLibECG.MSG_ECG_HEART_RATE:
				tv_heartrate.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_R2R_INTERVAL:
				tv_rrinterval.setText(String.valueOf(data));
				tv_heartbeat.setText(String.valueOf(libECG
						.getTotalRRintNum()));
				break;
			case TGLibECG.MSG_ECG_HRV:
				tv_hrv.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_RPEAK_DETECTED:
				if((Integer)data == 1) {
					tv_rpeak.setText(String.valueOf(data));
				}
				break;
			case TGLibECG.MSG_ECG_MOOD:
				tv_mood.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_STRESS:
				tv_stress.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_HEART_AGE:
				tv_heartage.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_HEART_RATE_ROBUST:
				tv_robusthr.setText(String.valueOf(data));
				break;
			case TGLibECG.MSG_ECG_EXCEPTION:
				Log.d(TAG,"MSG_ECG_EXCEPTION: " + String.valueOf(data));
				break;
			}
		}
	}
}
